package com.kexio.user.controller;

import java.lang.management.ManagementFactory;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.kexio.auth.annotation.RequiresPermission;
import com.kexio.common.dto.Result;
import com.kexio.user.entity.Permission;
import com.kexio.user.service.PermissionService;
import com.kexio.user.service.RoleService;
import com.kexio.user.service.UserService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * Dashboard控制器
 * 
 * 提供Dashboard相关的数据接口：
 * - 登录趋势数据
 * - 权限分布统计
 * - 系统信息
 * - 图表数据
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Tag(name = "Dashboard管理", description = "Dashboard数据接口")
@RestController
@RequestMapping("/dashboard")
public class DashboardController {
    
    private static final Logger logger = LoggerFactory.getLogger(DashboardController.class);
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private RoleService roleService;
    
    @Autowired
    private PermissionService permissionService;
    
    // @Autowired
    // private AuthService authService;
    
    // ==================== 登录趋势数据 ====================
    
    /**
     * 获取用户登录趋势数据（最近7天）
     */
    @GetMapping("/login-trend")
//    @RequiresPermission("dashboard:trend:query")
    @Operation(summary = "获取登录趋势", description = "获取最近7天的用户登录趋势数据")
    public Result<LoginTrendData> getLoginTrend() {
        
        logger.debug("获取登录趋势请求");
        
        LoginTrendData trendData = new LoginTrendData();
        
        // 生成最近7天的模拟数据（实际应该从登录日志表查询）
        List<String> dates = new ArrayList<>();
        List<Integer> loginCounts = new ArrayList<>();
        List<Integer> uniqueUsers = new ArrayList<>();
        
        LocalDate today = LocalDate.now();
        for (int i = 6; i >= 0; i--) {
            LocalDate date = today.minusDays(i);
            dates.add(date.format(DateTimeFormatter.ofPattern("MM-dd")));
            
            // 模拟数据（实际应该查询 login_log 表）
            loginCounts.add(50 + (int)(Math.random() * 50)); // 登录次数
            uniqueUsers.add(30 + (int)(Math.random() * 30));  // 独立用户数
        }
        
        trendData.setDates(dates);
        trendData.setLoginCounts(loginCounts);
        trendData.setUniqueUsers(uniqueUsers);
        
        logger.debug("获取登录趋势成功: days={}", dates.size());
        
        return Result.success("获取成功", trendData);
    }
    
    // ==================== 权限分布统计 ====================
    
    /**
     * 获取权限分布统计数据
     */
    @GetMapping("/permission-distribution")
//    @RequiresPermission("dashboard:permission:query")
    @Operation(summary = "获取权限分布", description = "获取权限类型分布的饼图数据")
    public Result<PermissionDistributionData> getPermissionDistribution() {
        
        logger.debug("获取权限分布请求");
        
        PermissionDistributionData distributionData = new PermissionDistributionData();
        
        // 获取所有权限
        List<Permission> allPermissions = permissionService.getPermissionsByTenant();
        
        if (allPermissions != null && !allPermissions.isEmpty()) {
            Map<String, Integer> typeCount = new HashMap<>();
            typeCount.put("操作权限", 0);
            typeCount.put("资源权限", 0); 
            typeCount.put("接口权限", 0);
            typeCount.put("其他权限", 0);
            
            // 统计各类型权限数量
            for (Permission permission : allPermissions) {
                if (permission.getType() != null) {
                    switch (permission.getType()) {
                        case "OP":
                            typeCount.put("操作权限", typeCount.get("操作权限") + 1);
                            break;
                        case "RESOURCE":
                            typeCount.put("资源权限", typeCount.get("资源权限") + 1);
                            break;
                        case "API":
                            typeCount.put("接口权限", typeCount.get("接口权限") + 1);
                            break;
                        default:
                            typeCount.put("其他权限", typeCount.get("其他权限") + 1);
                            break;
                    }
                } else {
                    typeCount.put("其他权限", typeCount.get("其他权限") + 1);
                }
            }
            
            // 转换为图表数据格式
            List<PermissionDistributionItem> items = new ArrayList<>();
            for (Map.Entry<String, Integer> entry : typeCount.entrySet()) {
                if (entry.getValue() > 0) {  // 只显示有数据的类型
                    PermissionDistributionItem item = new PermissionDistributionItem();
                    item.setName(entry.getKey());
                    item.setValue(entry.getValue());
                    items.add(item);
                }
            }
            
            distributionData.setItems(items);
            distributionData.setTotal(allPermissions.size());
            
        } else {
            // 没有权限数据时返回空数据
            distributionData.setItems(new ArrayList<>());
            distributionData.setTotal(0);
        }
        
        logger.debug("获取权限分布成功: total={}", distributionData.getTotal());
        
        return Result.success("获取成功", distributionData);
    }
    
    // ==================== 系统信息 ====================
    
    /**
     * 获取系统信息
     */
    @GetMapping("/system-info")
//    @RequiresPermission("dashboard:system:query")
    @Operation(summary = "获取系统信息", description = "获取系统运行信息")
    public Result<SystemInfo> getSystemInfo() {
        
        logger.debug("获取系统信息请求");
        
        SystemInfo systemInfo = new SystemInfo();
        
        // 获取系统基本信息
        systemInfo.setVersion("1.0.0");
        systemInfo.setEnvironment(System.getProperty("spring.profiles.active", "dev"));
        systemInfo.setJavaVersion(System.getProperty("java.version"));
        systemInfo.setOsName(System.getProperty("os.name"));
        systemInfo.setOsVersion(System.getProperty("os.version"));
        
        // 获取JVM信息
        Runtime runtime = Runtime.getRuntime();
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;
        
        systemInfo.setTotalMemory(totalMemory / (1024 * 1024) + " MB");
        systemInfo.setUsedMemory(usedMemory / (1024 * 1024) + " MB");
        systemInfo.setFreeMemory(freeMemory / (1024 * 1024) + " MB");
        systemInfo.setMemoryUsage(String.format("%.1f%%", (double) usedMemory / totalMemory * 100));
        
        // 获取启动时间
        long startTime = ManagementFactory.getRuntimeMXBean().getStartTime();
        systemInfo.setStartTime(Instant.ofEpochMilli(startTime).atZone(ZoneId.systemDefault()).toLocalDateTime());
        
        // 计算运行时长
        long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
        systemInfo.setUptime(formatUptime(uptime));
        
        // 租户模式配置（暂时硬编码，后续可从application.yml配置读取）
        systemInfo.setTenantEnabled(false);
        
        // 获取数据库信息
        // ✓ 保留此catch：数据库统计失败时设置默认值
        try {
            long userCount = userService.countUsers();
            long roleCount = roleService.countRolesByTenant(null);
            long permissionCount = permissionService.countPermissionsByTenant();
            
            systemInfo.setDatabaseInfo(String.format("用户:%d, 角色:%d, 权限:%d", 
                userCount, roleCount, permissionCount));
        } catch (Exception ex) {
            logger.warn("获取数据库统计信息失败: {}", ex.getMessage());
            systemInfo.setDatabaseInfo("数据库连接正常");
        }
        
        logger.debug("获取系统信息成功");
        
        return Result.success("获取成功", systemInfo);
    }
    
    // ==================== 工具方法 ====================
    
    /**
     * 格式化运行时长
     */
    private String formatUptime(long uptime) {
        long days = uptime / (24 * 60 * 60 * 1000);
        long hours = (uptime % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000);
        long minutes = (uptime % (60 * 60 * 1000)) / (60 * 1000);
        
        if (days > 0) {
            return days + "天" + hours + "小时" + minutes + "分钟";
        } else if (hours > 0) {
            return hours + "小时" + minutes + "分钟";
        } else {
            return minutes + "分钟";
        }
    }
    
    // ==================== 内部数据类 ====================
    
    /**
     * 登录趋势数据
     */
    public static class LoginTrendData {
        private List<String> dates = new ArrayList<>();
        private List<Integer> loginCounts = new ArrayList<>();
        private List<Integer> uniqueUsers = new ArrayList<>();
        
        // Getters and Setters
        public List<String> getDates() { return dates; }
        public void setDates(List<String> dates) { this.dates = dates; }
        
        public List<Integer> getLoginCounts() { return loginCounts; }
        public void setLoginCounts(List<Integer> loginCounts) { this.loginCounts = loginCounts; }
        
        public List<Integer> getUniqueUsers() { return uniqueUsers; }
        public void setUniqueUsers(List<Integer> uniqueUsers) { this.uniqueUsers = uniqueUsers; }
    }
    
    /**
     * 权限分布数据
     */
    public static class PermissionDistributionData {
        private List<PermissionDistributionItem> items = new ArrayList<>();
        private Integer total = 0;
        
        // Getters and Setters
        public List<PermissionDistributionItem> getItems() { return items; }
        public void setItems(List<PermissionDistributionItem> items) { this.items = items; }
        
        public Integer getTotal() { return total; }
        public void setTotal(Integer total) { this.total = total; }
    }
    
    /**
     * 权限分布项
     */
    public static class PermissionDistributionItem {
        private String name;
        private Integer value;
        
        // Getters and Setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public Integer getValue() { return value; }
        public void setValue(Integer value) { this.value = value; }
    }
    
    /**
     * 系统信息
     */
    public static class SystemInfo {
        private String version;
        private String environment;
        private String javaVersion;
        private String osName;
        private String osVersion;
        private String totalMemory;
        private String usedMemory;
        private String freeMemory;
        private String memoryUsage;
        private java.time.LocalDateTime startTime;
        private String uptime;
        private Boolean tenantEnabled;
        private String databaseInfo;
        
        // Getters and Setters
        public String getVersion() { return version; }
        public void setVersion(String version) { this.version = version; }
        
        public String getEnvironment() { return environment; }
        public void setEnvironment(String environment) { this.environment = environment; }
        
        public String getJavaVersion() { return javaVersion; }
        public void setJavaVersion(String javaVersion) { this.javaVersion = javaVersion; }
        
        public String getOsName() { return osName; }
        public void setOsName(String osName) { this.osName = osName; }
        
        public String getOsVersion() { return osVersion; }
        public void setOsVersion(String osVersion) { this.osVersion = osVersion; }
        
        public String getTotalMemory() { return totalMemory; }
        public void setTotalMemory(String totalMemory) { this.totalMemory = totalMemory; }
        
        public String getUsedMemory() { return usedMemory; }
        public void setUsedMemory(String usedMemory) { this.usedMemory = usedMemory; }
        
        public String getFreeMemory() { return freeMemory; }
        public void setFreeMemory(String freeMemory) { this.freeMemory = freeMemory; }
        
        public String getMemoryUsage() { return memoryUsage; }
        public void setMemoryUsage(String memoryUsage) { this.memoryUsage = memoryUsage; }
        
        public java.time.LocalDateTime getStartTime() { return startTime; }
        public void setStartTime(java.time.LocalDateTime startTime) { this.startTime = startTime; }
        
        public String getUptime() { return uptime; }
        public void setUptime(String uptime) { this.uptime = uptime; }
        
        public Boolean getTenantEnabled() { return tenantEnabled; }
        public void setTenantEnabled(Boolean tenantEnabled) { this.tenantEnabled = tenantEnabled; }
        
        public String getDatabaseInfo() { return databaseInfo; }
        public void setDatabaseInfo(String databaseInfo) { this.databaseInfo = databaseInfo; }
    }
}
